home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / src / gnome.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-27  |  15.5 KB  |  604 lines

  1. /* gnome.c-- support for the GNOME Hints
  2.  * 
  3.  *  Window Maker window manager
  4.  * 
  5.  *  Copyright (c) 1998, 1999 Alfredo K. Kojima
  6.  * 
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  20.  *  USA.
  21.  */
  22.  
  23. /*
  24.  * According to the author of this thing, it should not be taken seriously.
  25.  * IMHO, there are lot's of weirdnesses and it's quite unelegant. I'd
  26.  * rather not support it, but here it goes anyway. 
  27.  */
  28.  
  29. #include "wconfig.h"
  30.  
  31. #ifdef GNOME_STUFF
  32.  
  33. #include <X11/Xlib.h>
  34. #include <X11/Xutil.h>
  35. #include <X11/Xatom.h>
  36.  
  37. #include <stdlib.h>
  38. #include <stdio.h>
  39. #include <string.h>
  40.  
  41.  
  42. #include "WindowMaker.h"
  43. #include "screen.h"
  44. #include "wcore.h"
  45. #include "framewin.h"
  46. #include "window.h"
  47. #include "workspace.h"
  48. #include "funcs.h"
  49. #include "actions.h"
  50. #include "stacking.h"
  51.  
  52. #include "gnome.h"
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59. #define WIN_HINTS_SKIP_FOCUS      (1<<0) /*"alt-tab" skips this win*/
  60. #define WIN_HINTS_SKIP_WINLIST    (1<<1) /*do not show in window list*/
  61. #define WIN_HINTS_SKIP_TASKBAR    (1<<2) /*do not show on taskbar*/
  62. #define WIN_HINTS_GROUP_TRANSIENT (1<<3) /*Reserved - definition is unclear*/
  63. #define WIN_HINTS_FOCUS_ON_CLICK  (1<<4) /*app only accepts focus if clicked*/
  64.  
  65.  
  66. #define WIN_STATE_STICKY          (1<<0) /*everyone knows sticky*/
  67. #define WIN_STATE_MINIMIZED       (1<<1) /*Reserved - definition is unclear*/
  68. #define WIN_STATE_MAXIMIZED_VERT  (1<<2) /*window in maximized V state*/
  69. #define WIN_STATE_MAXIMIZED_HORIZ (1<<3) /*window in maximized H state*/
  70. #define WIN_STATE_HIDDEN          (1<<4) /*not on taskbar but window visible*/
  71. #define WIN_STATE_SHADED          (1<<5) /*shaded (MacOS / Afterstep style)*/
  72. /* these are bogus states defined in "the spec" */
  73. #define WIN_STATE_HID_WORKSPACE   (1<<6) /*not on current desktop*/
  74. #define WIN_STATE_HID_TRANSIENT   (1<<7) /*owner of transient is hidden*/
  75. #define WIN_STATE_FIXED_POSITION  (1<<8) /*window is fixed in position even*/
  76. #define WIN_STATE_ARRANGE_IGNORE  (1<<9) /*ignore for auto arranging*/
  77.  
  78.  
  79. #define WIN_LAYER_DESKTOP                0
  80. #define WIN_LAYER_BELOW                  2
  81. #define WIN_LAYER_NORMAL                 4
  82. #define WIN_LAYER_ONTOP                  6
  83. #define WIN_LAYER_DOCK                   8
  84. #define WIN_LAYER_ABOVE_DOCK             10
  85. #define WIN_LAYER_MENU                   12
  86.  
  87.  
  88.  
  89. static Atom _XA_WIN_SUPPORTING_WM_CHECK = 0;
  90. static Atom _XA_WIN_PROTOCOLS;
  91. static Atom _XA_WIN_LAYER;
  92. static Atom _XA_WIN_STATE;
  93. static Atom _XA_WIN_HINTS;
  94. static Atom _XA_WIN_APP_STATE;
  95. static Atom _XA_WIN_EXPANDED_SIZE;
  96. static Atom _XA_WIN_ICONS;
  97. static Atom _XA_WIN_WORKSPACE;
  98. static Atom _XA_WIN_WORKSPACE_COUNT;
  99. static Atom _XA_WIN_WORKSPACE_NAMES;
  100. static Atom _XA_WIN_CLIENT_LIST;
  101. static Atom _XA_WIN_DESKTOP_BUTTON_PROXY;
  102.  
  103.  
  104. void
  105. wGNOMEInitStuff(WScreen *scr)
  106. {
  107.     Atom supportedStuff[10];
  108.     int count;
  109.  
  110.     if (!_XA_WIN_SUPPORTING_WM_CHECK) {
  111.  
  112.     _XA_WIN_SUPPORTING_WM_CHECK = 
  113.         XInternAtom(dpy, "_WIN_SUPPORTING_WM_CHECK", False);
  114.  
  115.     _XA_WIN_PROTOCOLS = XInternAtom(dpy, "_WIN_PROTOCOLS", False);
  116.  
  117.     _XA_WIN_LAYER = XInternAtom(dpy, "_WIN_LAYER", False);
  118.  
  119.     _XA_WIN_STATE = XInternAtom(dpy, "_WIN_STATE", False);
  120.  
  121.     _XA_WIN_HINTS = XInternAtom(dpy, "_WIN_HINTS", False);
  122.  
  123.     _XA_WIN_APP_STATE = XInternAtom(dpy, "_WIN_APP_STATE", False);
  124.  
  125.     _XA_WIN_EXPANDED_SIZE = XInternAtom(dpy, "_WIN_EXPANDED_SIZE", False);
  126.  
  127.     _XA_WIN_ICONS = XInternAtom(dpy, "_WIN_ICONS", False);
  128.  
  129.     _XA_WIN_WORKSPACE = XInternAtom(dpy, "_WIN_WORKSPACE", False);
  130.  
  131.     _XA_WIN_WORKSPACE_COUNT = 
  132.         XInternAtom(dpy, "_WIN_WORKSPACE_COUNT", False);
  133.  
  134.     _XA_WIN_WORKSPACE_NAMES = 
  135.         XInternAtom(dpy, "_WIN_WORKSPACE_NAMES", False);
  136.  
  137.     _XA_WIN_CLIENT_LIST = XInternAtom(dpy, "_WIN_CLIENT_LIST", False);
  138.  
  139.     _XA_WIN_DESKTOP_BUTTON_PROXY = 
  140.         XInternAtom(dpy, "_WIN_DESKTOP_BUTTON_PROXY", False);
  141.     }
  142.  
  143.     /* I'd rather use the ICCCM 2.0 mechanisms, but
  144.      * since some people prefer to reinvent the wheel instead of
  145.      * conforming to standards... */
  146.  
  147.     /* setup the "We're compliant, you idiot!" hint */
  148.  
  149.     /* why XA_CARDINAL instead of XA_WINDOW? */
  150.     XChangeProperty(dpy, scr->root_win, _XA_WIN_SUPPORTING_WM_CHECK, 
  151.             XA_CARDINAL, 32, PropModeReplace, 
  152.             (unsigned char*)&scr->no_focus_win, 1);
  153.  
  154.     XChangeProperty(dpy, scr->no_focus_win, _XA_WIN_SUPPORTING_WM_CHECK, 
  155.             XA_CARDINAL, 32, PropModeReplace, 
  156.             (unsigned char*)&scr->no_focus_win, 1);
  157.  
  158.     
  159.     /* setup the "desktop button proxy" thing */
  160.     XChangeProperty(dpy, scr->root_win, _XA_WIN_DESKTOP_BUTTON_PROXY,
  161.             XA_CARDINAL, 32, PropModeReplace,
  162.             (unsigned char*)&scr->no_focus_win, 1);
  163.     XChangeProperty(dpy, scr->no_focus_win, _XA_WIN_DESKTOP_BUTTON_PROXY,
  164.             XA_CARDINAL, 32, PropModeReplace,
  165.             (unsigned char*)&scr->no_focus_win, 1);
  166.     
  167.  
  168.     /* setup the list of supported protocols */
  169.     count = 0;
  170.     supportedStuff[count++] = _XA_WIN_LAYER;
  171.     supportedStuff[count++] = _XA_WIN_STATE;
  172.     supportedStuff[count++] = _XA_WIN_HINTS;
  173.     supportedStuff[count++] = _XA_WIN_APP_STATE;
  174.     supportedStuff[count++] = _XA_WIN_EXPANDED_SIZE;
  175.     supportedStuff[count++] = _XA_WIN_ICONS;
  176.     supportedStuff[count++] = _XA_WIN_WORKSPACE;
  177.     supportedStuff[count++] = _XA_WIN_WORKSPACE_COUNT;
  178.     supportedStuff[count++] = _XA_WIN_WORKSPACE_NAMES;
  179.     supportedStuff[count++] = _XA_WIN_CLIENT_LIST;
  180.  
  181.     XChangeProperty(dpy, scr->root_win, _XA_WIN_PROTOCOLS, XA_ATOM, 32,
  182.             PropModeReplace, (unsigned char*)supportedStuff, count);
  183.  
  184.     XFlush(dpy);
  185. }
  186.  
  187.  
  188. void
  189. wGNOMEUpdateClientListHint(WScreen *scr)
  190. {
  191.     WWindow *wwin;
  192.     Window *windows;
  193.     int count;
  194.  
  195.     windows = malloc(sizeof(Window)*scr->window_count);
  196.     if (!windows) {
  197.     wwarning(_("out of memory while updating GNOME hints"));
  198.     return;
  199.     }
  200.  
  201.     count = 0;
  202.     wwin = scr->focused_window;
  203.     while (wwin) {
  204.     if (!wwin->flags.internal_window) {
  205.  
  206.         windows[count++] = wwin->client_win;
  207.     }
  208.  
  209.     wwin = wwin->prev;
  210.     }
  211.  
  212.     XChangeProperty(dpy, scr->root_win, _XA_WIN_CLIENT_LIST, XA_CARDINAL, 32,
  213.             PropModeReplace, (unsigned char *)windows, count);
  214.  
  215.     free(windows);
  216.     XFlush(dpy);
  217. }
  218.  
  219.  
  220. void
  221. wGNOMEUpdateWorkspaceHints(WScreen *scr)
  222. {
  223.     long val;
  224.  
  225.     val = scr->workspace_count;
  226.  
  227.     XChangeProperty(dpy, scr->root_win, _XA_WIN_WORKSPACE_COUNT, XA_CARDINAL,
  228.             32, PropModeReplace, (unsigned char*)&val, 1);
  229.  
  230.     wGNOMEUpdateWorkspaceNamesHint(scr);
  231. }
  232.  
  233.  
  234. void
  235. wGNOMEUpdateWorkspaceNamesHint(WScreen *scr)
  236. {
  237.     char *wsNames[MAX_WORKSPACES];
  238.     XTextProperty textProp;
  239.     int i;
  240.  
  241.     for (i = 0; i < scr->workspace_count; i++) {
  242.     wsNames[i] = scr->workspaces[i]->name;
  243.     }
  244.  
  245.     if (XStringListToTextProperty(wsNames, scr->workspace_count, &textProp)) {
  246.     XSetTextProperty(dpy, scr->root_win, &textProp,
  247.              _XA_WIN_WORKSPACE_NAMES);
  248.     XFree(textProp.value);
  249.     }
  250. }
  251.  
  252.  
  253. void
  254. wGNOMEUpdateCurrentWorkspaceHint(WScreen *scr)
  255. {
  256.     long val;
  257.  
  258.     val = scr->current_workspace;
  259.  
  260.     XChangeProperty(dpy, scr->root_win, _XA_WIN_WORKSPACE, XA_CARDINAL,
  261.             32, PropModeReplace, (unsigned char*)&val, 1);
  262. }
  263.  
  264.  
  265. static int
  266. getWindowLevel(int layer)
  267. {
  268.     int level;
  269.  
  270.     if (layer <= WIN_LAYER_DESKTOP)
  271.     level = WMDesktopLevel;
  272.     else if (layer <= WIN_LAYER_BELOW)
  273.     level = WMSunkenLevel;
  274.     else if (layer <= WIN_LAYER_NORMAL)
  275.     level = WMNormalLevel;
  276.     else if (layer <= WIN_LAYER_ONTOP)
  277.     level = WMFloatingLevel;
  278.     else if (layer <= WIN_LAYER_DOCK)
  279.     level = WMDockLevel;
  280.     else if (layer <= WIN_LAYER_ABOVE_DOCK)
  281.     level = WMSubmenuLevel;
  282.     else if (layer <= WIN_LAYER_MENU)
  283.     level = WMMainMenuLevel;
  284.     else 
  285.     level = WMOuterSpaceLevel;
  286.     
  287.     return level;
  288. }
  289.  
  290.  
  291. void
  292. wGNOMECheckClientHints(WWindow *wwin, int *layer, int *workspace)
  293. {
  294.     Atom type_ret;
  295.     int fmt_ret;
  296.     unsigned long nitems_ret;
  297.     unsigned long bytes_after_ret;
  298.     long flags, val, *data = 0;
  299.  
  300.     /* hints */
  301.     
  302.     if (XGetWindowProperty(dpy, wwin->client_win, _XA_WIN_HINTS, 0, 1, False,
  303.                /* should be XA_INTEGER, but spec is broken */
  304.                XA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret, 
  305.                &bytes_after_ret,
  306.                (unsigned char**)&data)==Success && data) {
  307.     flags = *data;
  308.     
  309.     XFree(data);
  310.     
  311.     if (flags & (WIN_HINTS_SKIP_FOCUS|WIN_HINTS_SKIP_WINLIST)) {
  312.         wwin->client_flags.skip_window_list = 1;
  313.     }
  314.     }
  315.  
  316.     /* layer */
  317.     if (XGetWindowProperty(dpy, wwin->client_win, _XA_WIN_LAYER, 0, 1, False,
  318.                XA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret, 
  319.                &bytes_after_ret,
  320.                (unsigned char**)&data)==Success  && data) {
  321.     val = *data;
  322.  
  323.     XFree(data);
  324.  
  325.     *layer = getWindowLevel(val);
  326.     }
  327.     
  328.     /* workspace */
  329.     if (XGetWindowProperty(dpy, wwin->client_win, _XA_WIN_WORKSPACE, 0, 1, 
  330.                False, XA_CARDINAL, &type_ret, &fmt_ret, 
  331.                &nitems_ret, &bytes_after_ret,
  332.                (unsigned char**)&data)==Success && data) {
  333.     val = *data;
  334.  
  335.     XFree(data);
  336.  
  337.     if (val > 0)
  338.         *workspace = val;
  339.     }
  340.  
  341.     /* reserved area */
  342.     if (XGetWindowProperty(dpy, wwin->client_win, _XA_WIN_EXPANDED_SIZE, 0, 1, 
  343.                False, XA_CARDINAL, &type_ret, &fmt_ret, 
  344.                &nitems_ret, &bytes_after_ret,
  345.                (unsigned char**)&data)==Success && data) {
  346.     WReservedArea *area;
  347.  
  348.     area = malloc(sizeof(WReservedArea));
  349.     if (!area) {
  350.         wwarning(_("out of memory while updating GNOME hints"));
  351.     } else {
  352.         area->area.x1 = data[0];
  353.         area->area.y1 = data[1];
  354.         area->area.x2 = data[2] - data[0];
  355.         area->area.y2 = data[3] - data[1];
  356.         XFree(data);
  357.  
  358.         area->window = wwin->client_win;
  359.     }
  360.  
  361.     area->next = wwin->screen_ptr->reservedAreas;
  362.     wwin->screen_ptr->reservedAreas = area;
  363.  
  364.         wScreenUpdateUsableArea(wwin->screen_ptr);
  365.     }
  366. }
  367.  
  368.  
  369. void
  370. wGNOMECheckInitialClientState(WWindow *wwin)
  371. {
  372.     Atom type_ret;
  373.     int fmt_ret;
  374.     unsigned long nitems_ret;
  375.     unsigned long bytes_after_ret;
  376.     long flags, *data = 0;
  377.  
  378.     if (XGetWindowProperty(dpy, wwin->client_win, _XA_WIN_STATE, 0, 1, False,
  379.                XA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret, 
  380.                &bytes_after_ret,
  381.                (unsigned char**)&data)!=Success || !data)
  382.     return;
  383.  
  384.     flags = *data;
  385.  
  386.     XFree(data);
  387.  
  388.     if (flags & WIN_STATE_STICKY)
  389.     wwin->client_flags.omnipresent = 1;
  390.  
  391.     if (flags & (WIN_STATE_MAXIMIZED_VERT|WIN_STATE_MAXIMIZED_HORIZ)) {
  392.  
  393.     if (flags & WIN_STATE_MAXIMIZED_VERT)
  394.         wwin->flags.maximized |= MAX_VERTICAL;
  395.  
  396.     if (flags & WIN_STATE_MAXIMIZED_HORIZ)
  397.         wwin->flags.maximized |= MAX_HORIZONTAL;
  398.     }
  399.  
  400.     if (flags & WIN_STATE_SHADED)
  401.     wwin->flags.shaded = 1;
  402. }
  403.  
  404.  
  405. void
  406. wGNOMEUpdateClientStateHint(WWindow *wwin, Bool changedWorkspace)
  407. {
  408.     long val;
  409.     long flags = 0;
  410.  
  411.     if (changedWorkspace) {
  412.     val = wwin->frame->workspace;
  413.  
  414.     XChangeProperty(dpy, wwin->client_win, _XA_WIN_WORKSPACE, XA_CARDINAL,
  415.             32, PropModeReplace, (unsigned char*)&val, 1);
  416.  
  417.     if (val != wwin->screen_ptr->current_workspace)
  418.         flags |= WIN_STATE_HID_WORKSPACE;
  419.     }
  420.  
  421.     if (IS_OMNIPRESENT(wwin))
  422.     flags |= WIN_STATE_STICKY;
  423.  
  424.     if (wwin->flags.miniaturized)
  425.     flags |= WIN_STATE_MINIMIZED;
  426.  
  427.     if (wwin->flags.maximized & MAX_VERTICAL)
  428.     flags |= WIN_STATE_MAXIMIZED_VERT;
  429.  
  430.     if (wwin->flags.maximized & MAX_HORIZONTAL)
  431.     flags |= WIN_STATE_MAXIMIZED_HORIZ;
  432.  
  433.     if (wwin->flags.shaded)
  434.     flags |= WIN_STATE_SHADED;
  435.  
  436.     if (wwin->transient_for != None) {
  437.     WWindow *owner = wWindowFor(wwin->transient_for);
  438.  
  439.     if (owner && !owner->flags.mapped)
  440.         flags |= WIN_STATE_HID_TRANSIENT;
  441.     }
  442.  
  443.     /* ? */
  444.     if (wwin->flags.hidden)
  445.     flags |= WIN_STATE_HIDDEN;
  446.  
  447.     XChangeProperty(dpy, wwin->client_win, _XA_WIN_STATE, XA_CARDINAL,
  448.             32, PropModeReplace, (unsigned char*)&flags, 1);
  449. }
  450.  
  451.  
  452. Bool
  453. wGNOMEProcessClientMessage(XClientMessageEvent *event)
  454. {
  455.     WScreen *scr;
  456.     WWindow *wwin;
  457.     Bool done = True;
  458.  
  459.     scr = wScreenForWindow(event->window);
  460.     if (scr) {
  461.     /* generic client messages */
  462.     if (event->message_type == _XA_WIN_WORKSPACE) {
  463.         wWorkspaceChange(scr, event->data.l[0]);
  464.     } else {
  465.         done = False;
  466.     }
  467.  
  468.     if (done)
  469.         return True;
  470.     }
  471.  
  472.     /* window specific client messages */    
  473.  
  474.     wwin = wWindowFor(event->window);
  475.     if (!wwin)
  476.     return False;
  477.     
  478.     if (event->message_type == _XA_WIN_LAYER) {
  479.     int level = getWindowLevel(event->data.l[0]);
  480.  
  481.     if (WINDOW_LEVEL(wwin) != level) {
  482.         ChangeStackingLevel(wwin->frame->core, level);
  483.     }
  484.     } else if (event->message_type == _XA_WIN_STATE) {
  485.     int flags, mask;
  486.     Bool updateWindowList = False;
  487.     int maximize = 0;
  488.  
  489.     mask = event->data.l[0];
  490.     flags = event->data.l[1]; 
  491.  
  492.     if (mask & WIN_STATE_STICKY) {
  493.         if ((flags & WIN_STATE_STICKY) != WFLAGP(wwin, omnipresent)) {
  494.         wwin->client_flags.omnipresent = 1;
  495.         updateWindowList = True;
  496.         }
  497.     }
  498.  
  499.     if (mask & WIN_STATE_MAXIMIZED_VERT) {
  500.         if (flags & WIN_STATE_MAXIMIZED_VERT)
  501.         maximize = MAX_VERTICAL;
  502.         else
  503.         maximize = 0;
  504.     } else {
  505.         maximize = wwin->flags.maximized & MAX_VERTICAL;
  506.     }
  507.  
  508.     if (mask & WIN_STATE_MAXIMIZED_HORIZ) {
  509.         if (flags & WIN_STATE_MAXIMIZED_HORIZ)
  510.         maximize |= MAX_HORIZONTAL;
  511.         else
  512.         maximize |= 0;
  513.     } else {
  514.         maximize |= wwin->flags.maximized & MAX_HORIZONTAL;
  515.     }
  516.  
  517.     if (maximize != wwin->flags.maximized) {
  518. #define both (MAX_HORIZONTAL|MAX_VERTICAL)
  519.         if (!(maximize & both) && (wwin->flags.maximized & both)) {
  520.         wUnmaximizeWindow(wwin);
  521.         }
  522.         if ((maximize & both) && !(wwin->flags.maximized & both)) {
  523.         wMaximizeWindow(wwin, maximize);
  524.         }
  525.         updateWindowList = False;
  526. #undef both
  527.     }
  528.  
  529.     if (mask & WIN_STATE_SHADED) {
  530.         if ((flags & WIN_STATE_SHADED) != wwin->flags.shaded) {
  531.         if (wwin->flags.shaded)
  532.             wUnshadeWindow(wwin);
  533.         else
  534.             wShadeWindow(wwin);
  535.         updateWindowList = False;
  536.         }
  537.     }
  538.  
  539.     if (updateWindowList) {
  540.         UpdateSwitchMenu(wwin->screen_ptr, wwin, ACTION_CHANGE_STATE);
  541.     }
  542.     } else if (event->message_type == _XA_WIN_WORKSPACE) {
  543.  
  544.     if (event->data.l[0] != wwin->frame->workspace) {
  545.         wWindowChangeWorkspace(wwin, event->data.l[0]);
  546.     }
  547.     } else {
  548.     done = False;
  549.     }
  550.     
  551.     return done;
  552. }
  553.  
  554.  
  555. Bool
  556. wGNOMEProxyizeButtonEvent(WScreen *scr, XEvent *event)
  557. {
  558.     if (event->type == ButtonPress)
  559.     XUngrabPointer(dpy, CurrentTime);
  560.     XSendEvent(dpy, scr->no_focus_win, False, SubstructureNotifyMask, event);
  561.  
  562.     return True;
  563. }
  564.  
  565.  
  566. void
  567. wGNOMERemoveClient(WWindow *wwin)
  568. {
  569.     int flag = 0;
  570.     WReservedArea *area;
  571.  
  572.     wGNOMEUpdateClientListHint(wwin->screen_ptr);
  573.     
  574.     area = wwin->screen_ptr->reservedAreas;
  575.  
  576.     if (area) {
  577.     if (area->window == wwin->client_win) {
  578.         wwin->screen_ptr->reservedAreas = area->next;
  579.         free(area);
  580.         flag = 1;
  581.     } else {
  582.         while (area->next && area->next->window != wwin->client_win) 
  583.         area = area->next;
  584.     
  585.         if (area->next) {
  586.         WReservedArea *next;
  587.         
  588.         next = area->next->next;
  589.         free(area->next);
  590.         area->next = next;
  591.         
  592.         flag = 1;
  593.         }
  594.     }
  595.     }
  596.  
  597.     if (flag) {
  598.     wScreenUpdateUsableArea(wwin->screen_ptr);
  599.     }
  600. }
  601.  
  602.  
  603. #endif /* GNOME_STUFF */
  604.